package org.dromara.web.plugins.weixin;


import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.ValidationException;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAPublicKeyConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RSAPublicKeyNotificationConfig;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.app.model.Transaction;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

@Slf4j
@Component
public class WeixinPayService implements InitializingBean {

    Config config = null;
    CertificatesManager certificatesManager = null;

    @Value("${weixin.appid}")
    private String appId;
    @Value("${weixin.mchid}")
    private String mchId;
    @Value("${weixin.privateKeyPath}")
    private String privateKeyPath;
    @Value("${weixin.publicKeyPath}")
    private String publicKeyPath;
    @Value("${weixin.publicKeyId}")
    private String publicKeyId;
    @Value("${weixin.merchantSerialNumber}")
    private String merchantSerialNumber;
    @Value("${weixin.apiV3PrivateKey}")
    private String apiV3PrivateKey;
    @Value("${weixin.notifyUrl}")
    private String notifyUrl;

    @Override
    public void afterPropertiesSet() throws Exception {
        config = new RSAPublicKeyConfig.Builder()
            .merchantId(mchId)
            .privateKeyFromPath(privateKeyPath)
            .publicKeyFromPath(publicKeyPath)
            .publicKeyId(publicKeyId)
            .merchantSerialNumber(merchantSerialNumber)
            .apiV3Key(apiV3PrivateKey)
            .build();


//        //获取商户私钥
//        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKeyFromPath(privateKeyPath);
//        certificatesManager = CertificatesManager.getInstance();
//
//
//        //向证书管理器增加需要自动更新平台证书的商户信息
//        certificatesManager.putMerchant(mchId, new WechatPay2Credentials(mchId,
//                new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)),
//            apiV3PrivateKey.getBytes(StandardCharsets.UTF_8));
    }



    public Transaction callbackSignVerify(String body, String nonce, String timeStamp, String signature, String wechatPaySerial) throws ValidationException {
//        //检验签名
//        Verifier verifier = certificatesManager.getVerifier(mchId);
//        String sn = verifier.getValidCertificate().getSerialNumber().toString(16).toUpperCase(Locale.ROOT);
//        NotificationRequest notifyRequest = new NotificationRequest.Builder().withSerialNumber(sn)
//            .withNonce(nonce)
//            .withTimestamp(timeStamp)
//            .withSignature(signature)
//            .withBody(body)
//            .build();
//        NotificationHandler handler = new NotificationHandler(verifier, apiV3PrivateKey.getBytes(StandardCharsets.UTF_8));
//
//        //验证和解析请求体
//        Notification notification = handler.parse(notifyRequest);
//        log.info("wx callback response:{}", JSON.toJSONString(notification));
//        return notification;
        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
            .serialNumber(wechatPaySerial)
            .nonce(nonce)
            .signature(signature)
            .timestamp(timeStamp)
            .body(body)
            .build();
        // 如果已经初始化了 RSAAutoCertificateConfig，可直接使用
// 没有的话，则构造一个
//        NotificationConfig config = new RSAAutoCertificateConfig.Builder()
//            .merchantId(mchId)
//            .privateKeyFromPath(privateKeyPath)
//            .merchantSerialNumber(merchantSerialNumber)
//            .apiV3Key(apiV3PrivateKey)
//            .build();
        // 1. 如果你使用的是微信支付公私钥，则使用 RSAPublicKeyNotificationConfig
        NotificationConfig config = new RSAPublicKeyNotificationConfig.Builder()
            .publicKeyFromPath(publicKeyPath)
            .publicKeyId(publicKeyId)
            .apiV3Key(apiV3PrivateKey)
            .build();

//        NotificationConfig config = new RSACombinedNotificationConfig.Builder()
//            .merchantId(mchId)
//            .privateKeyFromPath(privateKeyPath)
//            .merchantSerialNumber(merchantSerialNumber)
//            .publicKeyFromPath(publicKeyPath)
//            .publicKeyId(publicKeyId)
//            .apiV3Key(apiV3PrivateKey)
//            .build();

        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser(config);

        // 以支付通知回调为例，验签、解密并转换成 Transaction
        Transaction transaction = parser.parse(requestParam, Transaction.class);
        return transaction;

    }



    public PrepayResponse wechatJSAPIPay(String paymentOrderId, BigDecimal amount) {
        NativePayService payService = new NativePayService.Builder()
            .config(config)
            .build();

        PrepayRequest prepayRequest = new PrepayRequest();
        prepayRequest.setOutTradeNo(paymentOrderId);
        Amount amount1 = new Amount();
        BigDecimal total = amount.multiply(new BigDecimal(100));
        amount1.setTotal(total.intValue());
        prepayRequest.setAmount(amount1);
        prepayRequest.setAppid(appId);
        prepayRequest.setMchid(mchId);
        prepayRequest.setDescription("会员套餐购买");
        prepayRequest.setNotifyUrl(notifyUrl);


        PrepayResponse prepayResponse = payService.prepay(prepayRequest);

        return prepayResponse;
    }
}
